import type { ApiResult, Page, Pageable } from '@/utils/axios/types'
import { ApiCode } from '@/utils/axios/types'
import type { PaginationProps } from '@arco-design/web-vue/es/pagination/interface'
import type { AxiosResponse } from 'axios'
import { onMounted, ref, type Ref } from 'vue'

type PageListOptions<T> = Partial<{
  params: Ref<T>
  lazyLoad: boolean
  isList: boolean
}>

/**
 *
 * 封装table组件相关逻辑。
 */
export function usePageList<T, P extends Pageable>(
  fetchFn: (params: P) => Promise<AxiosResponse<ApiResult<Page<T>>, any>>,
  options?: PageListOptions<any>
): {
  pagination: Ref<PaginationProps>
  table_data: Ref<T[]>
  loading: Ref<boolean>
  reload: () => void
  reset: () => void
  handlePageChange: (page: number) => void
  handlePageSizeChange: (page_size: number) => void
} {
  const pagination = ref<PaginationProps>({
    current: options?.params?.value.page ?? 1,
    pageSize: options?.params?.value.page_size ?? 15,
    total: 0,
    showTotal: true
  })

  const table_data = ref<T[]>([]) as Ref<T[]>

  const loading = ref(false)

  const getData = () => {
    loading.value = true

    fetchFn({
      ...options?.params?.value,
      page: pagination.value.current,
      page_size: pagination.value.pageSize
    })
      .then((res) => {
        const { code, data } = res.data
        if (code === ApiCode.Success) {
          if (options?.isList) {
            table_data.value = data as any
          } else {
            table_data.value = data.list
            pagination.value.total = data.total
          }
        } else {
          table_data.value = []
        }
      })
      .finally(() => {
        loading.value = false
      })
  }

  const reload = () => {
    getData()
  }

  const reset = () => {
    pagination.value.current = 1
    getData()
  }

  onMounted(() => {
    if (!options?.lazyLoad) {
      getData()
    }
  })

  const handlePageChange = (page: number) => {
    pagination.value.current = page
    reload()
  }

  const handlePageSizeChange = (page_size: number) => {
    pagination.value.pageSize = page_size
    reload()
  }

  return {
    pagination,
    table_data,
    loading,
    reload,
    reset,
    handlePageChange,
    handlePageSizeChange
  }
}
